        TITL DAI FIRMWARE 3EDF9-3EFFF  V1.1
        ORG   :EDF9
*
*
*
********************************
* PRINT CONTENTS CPU SAVE AREA *
********************************
*
* Entry: HL: Points to register save area.
*        msb A = 0: 1 byte to be printed.
*        msb A = 1: 2 bytes to be printed.
* Exit:  msb A = 0: AFC corrupted, BDEHL preserved.
*        msb A = 1: AFCDE corrupted, BHL preserved.
*
L3E227  ORA   A         Test flags
        MOV   A,M       Get contents save area
        JP    :ED1D     1 byte: print it in ASCII
 REM
* If 2 bytes:
 REM
        MOV   E,M       Get contents in E
        INX   H         Next addr
        MOV   D,M       Its contents in D
        DCX   H         Restore HL
        PUSH  H         Save it on stack
        XCHG            Contents addr in HL
        CALL  :ED18     Print 2 bytes in ASCII
        POP   H         Restore HL
        RET
*
****************************************
* V+X: PRINT ROUTINE IF REGISTER GIVEN *
****************************************
*
* Entry: HL: Startaddress symbol table.
*        DE: Startaddress CPU save area.
*        A : Last input character.
* Exit:  All registers corrupted.
*
L3E228  MOV   B,A       Last input in B
        CALL  :ED01     Print space
L3E229  MOV   A,M       Get symbol from table
        ANI   :7F       Skip bit 7
        JZ    :EA62     Error if symbol=0
        CMP   B         Compare input with symbol
        JZ    :EE22     Jump if identical
        MOV   A,M       Get symbol
        RLC             Check for msb set
        INX   H         Next symbol
        INX   D         Next memory area
        JNC   :EE0D     Try next symbol
        INX   D         Next mem. area for '2 byte'
 REM symbols
        JMP   :EE0D     Try again
 REM
* If symbol found:
 REM
L3E230  PUSH  D         Save addr in mem.area
L3E231  MOV   A,M       Get symbol
        XTHL            HL: addr mem.area;
 REM stack: addr symbol
        PUSH  PSW       Save symbol
        CALL  :EDF9     Print contents mem.area
        POP   PSW       Retrieve symbol
        CALL  :EE6A     Exchange mem.contents,
 REM go to next one
        JC    :EE37     Jump if 'ESC'
        XTHL            HL: addr symbol,
 REM stack: next mem.area
        INX   H         addr next symbol
        MOV   A,M       Get symbol
        ORA   A         Set flags
        JNZ   :EE23     Not all symbols done
*
L3E232  POP   D         Retrieve next mem.area
        RET
*
************************
* V+X: DISPLAY ROUTINE *
************************
*
* Displays registers at succesive memory locations.
*
* Entry: DE: startaddress memory area to be
*            displayed.
*        HL: Startaddress symbol table.
* Exit:  All registers corrupted.
*
L3E233  CALL  :ED06     Scan keyb, print char
        CPI   :0D       'CR' ?
        JNZ   :EE09     Jump if also byte given
 REM
* If only 'V' or 'X':
 REM
        NOP
        NOP
        NOP
L3E234  PUSH  D         Save startaddr mem area
        MOV   C,M       Get symbol in C
        CALL  :EEB4     Print symbol
        MVI   C,:3D
        CALL  :EEB4     Print '='
        MOV   A,M       Get symbol in A
        ORA   A         Check flags
        XTHL            HL: startaddr mem.area
 REM stack: startaddr symboltable
        PUSH  PSW       Save symbol + flags
        CALL  :EDF9     Print contents mem.area
        POP   PSW       Retrieve symbol and flags
        INX   H
        JP    :EE5B     Jump if '1 byte' symbol
 REM
* If 2-byte symbol:
 REM
        INX   H
L3E235  NOP
        NOP
        NOP
        XTHL            HL: addr symbol
 REM stack: addr next mem.area
        INX   H         Next symbol
        POP   D         Get addr next mem.area
        MOV   A,M       Get symbol
        ORA   A
        RZ              Quit if ready
        CALL  :ED01     Print space
        JMP   :EE44     Next one
*
*****************************
* V+X: EVT. MODIFY CONTENTS *
*****************************
*
* Entry: HL: Memory address.
*        A : Symbol.
*
L3E326  ORA   A         Set flags on symbol
        PUSH  PSW       and save it
        MVI   C,:2D
        CALL  :EEB4     Print '-'
        PUSH  H         Save addr mem.area
        MVI   C,:01     Nr of datablocks allowed
        CALL  :EB07     Get input on stack; last
 REM byte typed in in B
        DCR   C
        JZ    :EE87     Jump if incorrect input
        POP   D         Data typed in in DE
        POP   H         Get addr mem.area
        POP   PSW       Get symbol and flags
        MOV   M,E       Change memory contents
        JP    :EE8D     Jump if '1 byte' symbol
 REM
* If 2-byte symbol:
 REM
        INX   H
        MOV   M,D       Change 2nd byte
        JMP   :EE8D
*
L3E327  POP   H         Retrieve addr mem.area
        POP   PSW       Retrieve symbol + flags
        JP    :EE8D     If '1 byte' symbol
        INX   H         Add. INX H if 2-byte symbol
L3E328  INX   H         Next mem.area
        MOV   A,B       Get last input
        CPI   :0D
        RZ              Ready if 'CR'
        CPI   :20
        RZ              Ready if 'SP'
        CPI   :12
        STC             Abort with CY=1 if 'ESC'
        RZ
        JMP   :EA62     Else: wrong input: Error
*
****************************
* SYMBOL TABLE EXAMINE (X) *
****************************
*
* The msb is '1' for symbols of two-byte
* registers.
*
L3E405  DATA  :C9       I (addr current instr)
        DATA  :41       A
        DATA  :46       F (flags)
        DATA  :42       B
        DATA  :43       C
        DATA  :44       D
        DATA  :45       E
        DATA  :48       H
        DATA  :4C       L
        DATA  :D3       S (stackpointer)
        DATA  :D0       P (program counter)
        DATA  :00
*
*******************************
* SYMBOL TABLE VECTOR EXAMINE *
*******************************
*
* The msb is '1' for symbols of two-byte
* registers.
*
L3E406  DATA  :4D       M (TICC int mask)
        DATA  :54       T (TICC cmd + comm.reg)
        DATA  :47       G (GIC cmd word)
        DATA  :B0       0  )
        DATA  :B1       1  )
        DATA  :B2       2  )
        DATA  :B3       3  ) Interrupt vectors
        DATA  :B4       4  ) addresses
        DATA  :B5       5  )
        DATA  :B6       6  )
        DATA  :B7       7  )
        DATA  :00
*
*******************
* PRINT CHARACTER *
*******************
*
* Entry: C: Character to be printed.
* Exit:  AF corrupted, BCDEHL preserved.
*
CO      MOV   A,C       Char in A
        JMP   :DD60     Print char
*
*******************************
* SCAN KEYBOARD; IGNORE BREAK *
*******************************
*
* Exit: Character in A.
*       BCDEHL preserved.
*
CI      CALL  :EF83     Scan keyboard
        JC    :EEB8     Ignore break
        JZ    :EEB8     Wait for input
        RET
*
***********************************
* SCAN KEYBOARD FOR BREAK PRESSED *
***********************************
*
* Exit: CY=0: No break.
*       CY=1: Break pressed.
*       A corrupted, BCDEHL preserved.
*
BREAK   CALL  :D6A5     Scan keyb for new inputs
        RNC             abort if Break not pressed
        JMP   :EA6A     Restore SP, wait for
 REM new inputs
*
*
*********************
* CASSETTE ROUTINES *
*********************
*
L3E335  JMP   :02C5     WOPEN
*
        DATA  :FF
        DATA  :FF
        DATA  :FF
*
L3E336  JMP   :02C8     WBLK
*
        DATA  :FF
        DATA  :FF
        DATA  :FF
*
L3E337  JMP   :02CB     WCLOSE
*
L3E338  JMP   :02CE     ROPEN
*
        DATA  :FF
        DATA  :FF
        DATA  :FF
*
L3E339  JMP   :02D1     RBLK
*
L3E340  JMP   :02D4     RCLOSE
*
*************
* W - WRITE *
*************
*
* Requires 2 address fields + evt. name.
* Filetype is '1'. Writes startaddress of datablock
* + data + trailer on tape.
*
L3E341  MVI   C,:02     Nr of addr allowed
        CALL  :EADE     Scan keyb, addr on stack
        DCR   C         2 addr given ?
        JP    :EA62     Error if not
        CALL  :EF48     Evt. name in input buffer
        MVI   A,:31     File type byte
        NOP
        NOP
        NOP
        NOP
        NOP
        NOP
        CALL  :EEC9     Write file header on tape
        POP   D         Get haddr from stack
        INX   D         Incr it
        POP   H         Get laddr from stack
        CALL  :EF63     Write startaddr on tape
        MOV   A,E       )
        SUB   L         )
        MOV   E,A       ) Calc length of data
        MOV   A,D       ) block, result in DE
        SBB   H         )
        MOV   D,A       )
        NOP
        CALL  :EECF     Write datablock on tape
        CALL  :EED5     Write file trailer
        RET
*
************
* R - READ *
************
*
* One address is allowed. An evt. name is stored
* in the EBUF. Reads header, startaddress and data
* from tape. Errorcheck only on data.
*
* Exit: HL: 1st address above file loaded.
*       BC: Evt. offset.
*       AFDE corrupted.
*
RHEXK   MVI   C,:01     Nr of addr allowed
        CALL  :EADE     Scan keyb; addr on stack
        CALL  :EF48     Evt name in input buffer
        MVI   B,:31     File type byte
        NOP
        NOP
        NOP
        MVI   C,:00
        CALL  :EED8     Read file header
        LXI   D,:F900   Max addr to write data into
        POP   B         Get evt offset from stack
        CALL  :EF74     Read startaddr from tape
        DAD   B         Add offset
        CALL  :EF8A     Read data block + trailer
        JNC   :EA62     Print 'error' if reading
 REM error
        RET
*
***************************************
* RST 0: POINTER TO 'LOOK'-FLAG IN HL *
***************************************
*
* Part of 3EC21.
*
* Exit: A=0, BCDE preserved.
*
L3E343  XRA   A
        LXI   H,:0050
        RET
*
********************
* INITIALISE RST 0 *
********************
*
* Entry: On stack: Returnaddress #EA42.
*
L3E344  MVI   A,:FB     Instr code for EI in A
        STA   :0047     Save it
        POP   D         Get EA42 in DE
        JMP   :EBE2     Into RST 0
*
**********************
* SET INTERRUPT MASK *
**********************
*
* Part of RST0 (3EC05).
*
* Entry: A: Value for TICC interrupt mask.
* Exit:  A=0, F corrupted, BCDEHL preserved.
*
L3E345  STA   :FFF8     Set TICC int mask
        XRA   A         A=0
        RET
*
        DATA  :FF
*
*************************
* part of RST 0 (3EC3B) *
*************************
*
L3E346  DCX   H
        JMP   :EC19     Into RST 0
*
*****************************
* W+R: NAME IN INPUT BUFFER *
*****************************
*
* Names >126 characters destroy BASIC pointers.
*
* Entry: Last character typed in, in B.
* Exit:  BCD preserved. HL points to EBUF.
*        A= 0: No file name given.
*        A<>0: File name given.
*
L3E347  LXI   H,:013E   Startaddr EBUF
        MVI   E,:FF
        MOV   A,B       Last char in A
        SUI   :0D       'CR' ?
        MOV   M,A       (13E) is 0 if CR
        RZ              Quit if no name given
 REM
* If name given:
 REM
        PUSH  H         Save startaddr EBUF
L3E356  INR   L         Points to next loc
        INR   E         Calc length
        CALL  :ED06     Scan keyb, print char
        MOV   M,A       Char into EBUF
        CPI   :0D
        JNZ   :EF53     Next char if not 'CR'
        POP   H         Retrieve startaddr EBUF
        MOV   M,E       Store length name in 013E
        RET
*
**************
* (Not used) *
**************
*
L3E348  POP   H
        RET
*
******************************
* WRITE STARTADDRESS ON TAPE *
******************************
*
* Entry: HL: Startaddress.
* Exit:  AF corrupted, BCDEHL preserved.
*
L3E349  PUSH  D
        PUSH  H
        SHLD  :013E     Startaddr in EBUF
        LXI   H,:013E   Startaddr to write from
        LXI   D,:0002   Length
        CALL  :EECF     Write addr on tape
        POP   H
        POP   D
        RET
*
*******************************
* READ STARTADDRESS FROM TAPE *
*******************************
*
* Exit: HL: Startaddress.
*       CY=1: No reading error.
*       CY=0: Reading error, errorcode in A.
*       BCDE preserved.
*
L3E350  PUSH  D
        LXI   H,:013E   Addr EBUF
        LXI   D,:0141   Addr after addr in EBUF
        CALL  :EEDE     Read block from tape
        POP   D
        LHLD  :013E     Startaddr in HL
        RET
*
*****************
* SCAN KEYBOARD *
*****************
*
* Part of 3EEB8. Scans keyboard. Returns
* any key received.
*
* Exit: A: Key received.
*       BCDEHL preserved.
*       CY=1: Break pressed.
*
L3E351  XRA   A
        STA   :02B9     Enable complete keyb scan
        JMP   :D6BE     Scan keyboard
*
***********************
* READ DATA FROM TAPE *
***********************
*
* Part of READ (3EF29).
*
L3E352  CALL  :EEDE     Read block from tape
        JMP   :EEE1     Stop reading
*
******************************
* DCE INITIALISATION ROUTINE *
******************************
*
* Part of RESET (C719). Bootstrap for disc drive.
* Sets GIC in initialisation status. Checks if any
* input is received from the DCE-bus and performs
* the received instructions.
*
* Exit: A=#EE if no DCE-inputs available.
*
L3E353  MVI   A,:98
        STA   :FE03     PA+PCH in, PB+PCL out
        MVI   A,:07
        STA   :FE03     PC3=1
        MVI   A,:01
        STA   :FE01     Output PB: 01
        MVI   A,:01
        STA   :FE03     PC0=1
        LXI   B,:1000
L3E355  LDA   :FE02     Get input from PCH
        ANI   :20       Bit 5 only
        JNZ   :EFB8     Jump if inputs received
 REM
* If no inputs:
 REM
        DCX   B         )
        MOV   A,B       ) Wait loop until C=#10
        ORA   C         )
        JNZ   :EFA7     )
        MVI   A,:EE     A=EE if no inputs
        RET
*
* DCE BOOTSTRAP INPUT ROUTINE:
*
* Loads MLP inputs from the DCE-bus into the
* stackbottom and goes to it.
*
L3E354  LXI   D,:F800   Addr stackbottom
L3E357  MVI   A,:05
        STA   :FE03     PC2=1
L3E358  LDA   :FE02     Get input from PC
        ANI   :80       Bit 7 only
        JZ    :EFC0     Wait for change to high
        LDA   :FE00     Get input from FA
        STAX  D         Save input in stack area
        INX   D         Point to next loc
        MVI   A,:04
        STA   :FE03     PC2=0
L3E359  LDA   :FE02     Get input from PC
        ANI   :80       Bit 7 only
        JNZ   :EFD2     Wait for change to low
        LDA   :FE02     Get input from FC
        ANI   :20       Bit 5 only
        JNZ   :EFBB     Again if high
        MVI   A,:06
        STA   :FE3E     (FE3E hardwarewise read as
 REM FE02). PC=06
L3E360  LDA   :FE02     Get input from FC
        ANI   :20       Bit 5 only
        JZ    :EFE7     Wait for change to high
        JMP   :F800     Go to stackbottom
*
        DATA  :FF
        DATA  :FF
*
*********************
* SCAN 'DINC' INPUT *
*********************
*
* Part of 3E935. Default 'DINC' is RS232 input.
*
L3E361  CALL  :DDB4     Get input from DINC
        JZ    :E935     Scan keyb if no DINC input
 REM
* If inputs from DINC:
 REM
        MVI   A,:01
        STA   :0296     Set INSW for DINC input
        RET
*
*
*
        END
